/**
 * Copyright (C), 2020-2021 by colley.ma
 * File Name: ExtensionAutoConfiguration.java
 * Encoding: UTF-8
 * Date: 2021年3月31日 上午11:25:08
 * History:
 */
package com.swak.frame.datarchive.spring.configuration;

import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import com.google.common.collect.Maps;
import com.swak.frame.SwakConstants;
import com.swak.frame.datarchive.config.ArchivemailConfig;
import com.swak.frame.datarchive.config.DataArchiveProperties;
import com.swak.frame.datarchive.constants.DataArchiveConstants;
import com.swak.frame.datarchive.notify.AlarmArchiveLogMonitor;
import com.swak.frame.mybatis.archiver.ArchiverClientFactoryBean;
import com.swak.frame.mybatis.archiver.conf.EmailConfig;
import com.swak.frame.mybatis.archiver.executor.ArchiverDataEngine;
import com.swak.frame.mybatis.archiver.notify.JavaEmailClientFactory;
import com.swak.frame.mybatis.common.SwakTemplateExecutor;
import com.swak.frame.mybatis.constants.SwakDataBaseConstants;
import com.swak.frame.mybatis.spring.configuration.SwakDataBaseAutoConfiguration;
import com.swak.frame.registry.SwakBeanDefinitionRegistry;
import com.swak.frame.ump.BizAlarmAdapter;

/**
 * ClassName: SwakArchiveAutoConfiguration.java
 * 
 * @author colley.ma
 * @date 2021年10月12日 上午10:42:34
 */
@AutoConfigureAfter(SwakDataBaseAutoConfiguration.class)
@Configuration
@EnableConfigurationProperties(DataArchiveProperties.class)
@ConditionalOnProperty(prefix = SwakConstants.SWAK_ARCHIVE, name = "enabled", havingValue = "true",
    matchIfMissing = false)
public class SwakDataArchiveAutoConfiguration extends SwakBeanDefinitionRegistry {

    @Bean(DataArchiveConstants.ARCHIVE_TRANSACTION_MANAGER)
    @Autowired
    public PlatformTransactionManager dataArchiveTransactionManager(final DataArchiveProperties archiveProperties) {
        return new DataSourceTransactionManager(getDataSource(archiveProperties));
    }

    @Bean(DataArchiveConstants.ARCHIVE_TRANSACTION_TEMPLATE)
    public TransactionTemplate dataArchiveTransactionTemplate(
        @Qualifier(DataArchiveConstants.ARCHIVE_TRANSACTION_MANAGER) final PlatformTransactionManager dataArchiveTransactionManager) {
        return new TransactionTemplate(dataArchiveTransactionManager);
    }

    @Bean(DataArchiveConstants.ARCHIVE_EMAIL_CLIENT)
    public JavaEmailClientFactory dataArchiveEmailClient(final DataArchiveProperties archiveProperties) {
        EmailConfig.Builder builder = new EmailConfig.Builder();
        ArchivemailConfig mail = archiveProperties.getEmail();
        builder.host(mail.getHost()).port(mail.getPort()).defaultEncoding(mail.getDefaultEncoding())
            .username(mail.getUsername()).password(mail.getPassword());
        Properties javaMailProperties = new Properties();
        javaMailProperties.put("mail.smtp.auth", mail.isSmtpAuth());
        javaMailProperties.put("mail.debug", mail.isDebug());
        builder.javaMailProperties(javaMailProperties).senderName(mail.getSenderName()).sender(mail.getSender());
        return new JavaEmailClientFactory(builder.build());
    }

    @Bean(DataArchiveConstants.ARCHIVE_ENGINE_EXECUTOR)
    public ArchiverDataEngine dataArchiveEngineExecutor(final DataArchiveProperties archiveProperties,
        @Qualifier(DataArchiveConstants.ARCHIVE_TRANSACTION_TEMPLATE) final TransactionTemplate transactionTemplate,
        @Qualifier(DataArchiveConstants.ARCHIVE_EMAIL_CLIENT) final JavaEmailClientFactory dataArchiveEmailClient)
        throws Exception {
        ArchiverClientFactoryBean factoryBean = new ArchiverClientFactoryBean();
        Map<String, Object> swakTemplateExecutor = Maps.newHashMap();
        swakTemplateExecutor.put("dataSource", getDataSource(archiveProperties));
        swakTemplateExecutor.put("transactionTemplate", transactionTemplate);
        swakTemplateExecutor.put("readDatasource", false);
        registerIfNotExists(DataArchiveConstants.ARCHIVE_TEMPLATE_EXECUTOR, SwakTemplateExecutor.class,
            swakTemplateExecutor);

        AlarmArchiveLogMonitor monitor = new AlarmArchiveLogMonitor();
        monitor.setEmailClient(dataArchiveEmailClient);
        monitor.setMessageTemplateFile(DataArchiveConstants.MESSAGE_TEMPLATE_FILE);
        monitor.setBizAlarmAdapter(beanFactory.getBean(BizAlarmAdapter.class));
        factoryBean.setExecutor(
            beanFactory.getBean(DataArchiveConstants.ARCHIVE_TEMPLATE_EXECUTOR, SwakTemplateExecutor.class));
        factoryBean.setMonitor(monitor);

        return factoryBean.getObject();
    }

    private DataSource getDataSource(final DataArchiveProperties archiveProperties) {
        String dataSourceBeanName = archiveProperties.getDataSoruceName();
        if (StringUtils.isEmpty(dataSourceBeanName)) {
            dataSourceBeanName = SwakDataBaseConstants.MASTER;
        }
        DataSource dataSource = beanFactory.getBean(dataSourceBeanName, DataSource.class);
        return dataSource;
    }

    /**
     * <bean id="dataArchiveTransactionManager" class=
     * "org.springframework.jdbc.datasource.DataSourceTransactionManager">
     * <property name="dataSource" ref="${data.archiver.dataSoruce.name}" />
     * </bean>
     * 
     * <bean id="dataArchiveTransactionTemplate" class=
     * "org.springframework.transaction.support.TransactionTemplate">
     * <property name="transactionManager" ref="dataArchiveTransactionManager" />
     * </bean>
     * 
     * <bean id="dataArchiveEmailClient" class=
     * "com.swak.frame.mybatis.archiver.notify.JavaEmailClientFactory">
     * <property name="emailConfig">
     * <bean class="com.swak.frame.mybatis.archiver.conf.EmailConfig">
     * <!-- 设置smtp服务器地址 -->
     * <property name="host" value="${data.archiver.mail.host}" />
     * <!-- 设置smtp服务器端口 -->
     * <property name="port" value="${data.archiver.mail.port}" />
     * <!-- 编码格式 -->
     * <property name="defaultEncoding" value="UTF-8" />
     * <property name="username" value="${data.archiver.mail.username}" />
     * <property name="password" value="${data.archiver.mail.password}" />
     * <property name="javaMailProperties">
     * <props>
     * <!-- 是否需要认证 -->
     * <prop key="mail.smtp.auth">true</prop>
     * <prop key="mail.debug">false</prop>
     * </props>
     * </property>
     * <property name="senderName" value="${data.archiver.mail.sendername}" />
     * <property name="sender" value="${data.archiver.mail.sender}" />
     * </bean>
     * </property>
     * </bean>
     * 
     * <bean id="dataArchiveEngineExecutor" class=
     * "com.swak.frame.mybatis.archiver.ArchiverClientFactoryBean">
     * <property name="executor">
     * <bean class="com.swak.frame.mybatis.common.SwakTemplateExecutor">
     * <property name="dataSource" ref="${data.archiver.dataSoruce.name}" />
     * <property name="transactionTemplate" ref="dataArchiveTransactionTemplate" />
     * <property name="readDatasource" value="false" />
     * </bean>
     * </property>
     * <property name="monitor">
     * <bean class="com.swak.frame.mybatis.archiver.notify.ArchiveLogMonitor">
     * <property name="emailClient" ref="dataArchiveEmailClient" />
     * <property name="messageTemplateFile" value=
     * "archiver/template/email/templateArchiver.htm" />
     * </bean>
     * </property>
     * </bean>
     */

}
